/** 
 * 游戏场景
 * Author      : donggang
 * Create Time : 2016.9.18　　　　　　　　　　　　　　　　　　   
 */
var SceneAnimation = require("SceneAnimation");

module.exports = cc.Class({
    extends: cc.Node,

    /**
     * 加载新场景
     * @param newUiResPath(string)                           新界面资源地址
     * @param operate{
     *      preloaded : "common/image"|['a.png', 'b.png']    预加载文件夹
     *      params    : [a,b,c]                              自定义参数，在新界面的added事件中接受
     *      sign      : false                                是否标记新的内存块并释放上一个内存块
     * }
     * @param complete(function(node))                       转场完成事件
     */
    load : function(newUiResPath, operate, complete){          
        this._layers = {};           

        // 场景层初始化
        this._initLayers();

        // 添加游戏主场景
        this.getChildByName(game.SceneLayerType.UI).add(newUiResPath, operate, complete);
    },

    /** 场景层初始化 */
    _initLayers : function(){
        var UiLayer          = require("UiLayer");
        var UiLayerPop       = require("UiLayerPop");　
        var UiLayerPopStatic = require("UiLayerPopStatic");
        var UiLayerToast     = require("UiLayerToast");
        
        this.addChild(new UiLayer());
        this.addChild(new UiLayerPop());
        this.addChild(new UiLayerPopStatic());
        this.addChild(new UiLayerToast());
    },

    /** 
     * 替换界面
     * @param newUiResPath(string)                                新界面资源地址
     * @param operate{
     *      preloaded      : "common/image"|['a.png', 'b.png']    预加载文件夹
     *      handler        : function                             预加回调方法
     *      params         : [a,b,c]                              自定义参数，在新界面的added事件中接受
     *      animationOpen  : path(string),clip(string)            新场景打开动画（两个动画必须同时存在）
     *      animationClose : path(string),clip(string)            旧场景关闭动画（两个动画必须同时存在）
     *      cleanup        : true                                 是否清理上个界面资源内存
     * }
     */
    replaceUi : function(newUiResPath, operate){
        var uiLayer      = this.getChildByName(game.SceneLayerType.UI);
        var previousNode = uiLayer.childrenCount == 0 ? null : uiLayer.children[0];

        if (this._isReplaceUi) {
            cc.error("正有一个界面【{0}】在替换中，在当前界面替换完成前不能在替换界面".format(previousNode.manager_data.resPath));
            return;
        }

        if (uiLayer.childrenCount > 1) { 
            cc.error("常驻界面层同时只能存在一个预制界面");
            return;
        }  

        // 打开场景事件遮挡
        SceneAnimation.blockEventOpen();

        var onReplaceUiComplete = function(currentNode){
            // 关闭动画 
            var isReplace = true;

            // 转场动画 - 预制动画
            isReplace = SceneAnimation.createAnimationByPrefab(previousNode, currentNode, operate, function(){
                this._releaseRreviousUi(uiLayer, previousNode, currentNode, operate);
            }.bind(this));

            if (isReplace == false){
                this._releaseRreviousUi(uiLayer, previousNode, currentNode, operate); 
            }
        }.bind(this);

        this._isReplaceUi = true;
        uiLayer.add(newUiResPath, operate, onReplaceUiComplete);
    },

    /** 释放上一个场景资源 */
    _releaseRreviousUi : function(uiLayer, previousNode, currentNode, operate){
        if (previousNode) {
            // 设置上一个场景内存是否释放
            if (operate == null || operate.cleanup == null || operate.cleanup == true){
                uiLayer.remove(previousNode, true);
            }
            else{
                uiLayer.remove(previousNode, false);
            }
        }

        this._isReplaceUi = false;

        // 关闭场景事件遮挡 
        SceneAnimation.blockEventClose();

        // 触发当前界面动画转换完成第一部分事件
        currentNode.applyComponentsFunction("onReplaceAnimationMiddle");  
        
        if (game.MemoryConfig.replaceUi)  
            cc.textureCache.memory(); 
    },

    /** 
     * 清除所有逻辑层节点 
     * @param cleanup(boolen)                       是否清理在实例管理器中的缓存
     */
    clear : function(cleanup = false) {
        for(var i = 0; i < this.childrenCount; i++) {
            this.children[i].clear(cleanup);
        }
    }
});
